Real-time operating environments enable computers to perform time-constrained functions. Examples of time-constrained functions include executing tasks at regular time intervals (e.g., automatically updating a user interface), running a program at a given time (e.g., reading input from a peripheral for a given period of time), or delaying the execution of a task for a given time period. Any of the latter functions may be triggered, for example, by a timer and/or a software event.
A real-time operating system typically comprises a kernel and a number of applications and drivers. The kernel is the part of the operating system that manages the execution of applications and the inputs and outputs through drivers. A task, in computer code terms, is a piece of code (e.g., computer application or a part thereof) designed to enable the computer to provide a given functionality. Modern real-time operating systems are able to virtually simultaneously execute more than one task by switching from one task to another, an operation that requires sharing execution time in a scheduled manner (conventionally referred as “time-slicing”). The kernel determines, at each time period, the next task to execute/resume. Thus, in existing real-time operating systems, each task must be designed to be able to execute, suspend execution, resume execution, and stop. For instance, a task may need to stop in order to wait for new input, or when it is preempted by another task. The system utilizes a stack to be able to store the state of a task when stopping its execution, and re-establish its state when the execution resumes. Since modern programs typically use a stack to execute function calls, a task needs its own stack in order to run, stop and resume running. For example, in the case of switching from a task “A” to a task “B”, the system switches the execution context from task “A” to task “B” by saving the registers of task “A” to stack of “A”, then restoring (previously saved) registers of task “B” from stack “B”. Furthermore, a task possesses a unique entry point. The entry point comprises a mailbox (or message queue). The mailbox receives messages, and a dispatcher dispatches each message to the appropriate part of the program code within a task once it is invoked.
The purpose of a task-based architecture in real-time operating systems is the ability to handle time-sensitive tasks, thus the need to switch between multiple tasks on the basis of each task's priority level. The priority level allows the real-time operating system to determine which task is to be executed at any time slice or following an interrupt. For instance, a low priority task can run the main algorithms, while a higher priority task can execute time sensitive code. The high priority task preempts the low priority task at almost any point in time.
Existing real-time operating systems present many limitations with regard to task management. For a software engineer, developing programs for a real-time operating system is a time-consuming and error prone endeavor. A programmer must manually assign priority levels and create messages for communications between different tasks. For example, if a function “F” runs in task “A”, it is impossible to call it from task “B” in existing systems. The way to call function “F” is by sending a message to task “B”, the message containing information regarding which function to call and including the parameters to pass to function “F”. In existing real-time operating systems architecture, the developer is compelled to manually assign functions to tasks and write messages to transmit between tasks, which increases development time and reduces the modularity of a program.
Therefore, there is a need for an improved architecture that allows a programmer to automatically implement program management tools in order to facilitate runtime task switching.